import { toRefs } from 'vue'

// 自定义指令：https://cn.vuejs.org/guide/reusability/custom-directives.html#introduction

const tableClick = {
  // el：当前元素
  // bindings：一个对象
  mounted(el, bindings) {
    // console.log(el, bindings)

    // const { userList, status } = bindings.value
    const { userList, status, field, index, socket } = toRefs(bindings.value)  // 将status变成响应时数据（加上toRefs）即可


    // 外部也能访问tableClick中的数据
    tableClick.element = el
    tableClick.userList = userList
    tableClick.status = status
    tableClick.field = field
    tableClick.index = index
    tableClick.socket = socket.value

    // 执行绑定的事件
    bindEvent()
  }
}

// 绑定事件处理函数
function bindEvent() {
  tableClick.element.addEventListener('click', handleTableClick, false)
  // 点击其他地方要取消编辑状态（点击其他地方要把oInput删掉）
  window.addEventListener('click', handleWindowClick, false)
}
// 事件处理回调函数
function handleTableClick(e) {
  // 点击之前阻止冒泡
  handleStopPropagation(e)
  // 点击的时候把上一次的input清空
  handleWindowClick()

  /**
   * html代码：<p data-field="name"></p>
   * js获取html元素上的自定义属性：
   *    1. 首先你要先拿到这个元素
   *    2. document.querySelector('p').setdata.field
   * 
   * 
   * Element.tagName 该方法，返回当前元素的标签名（是大写的）,比如：SPAN、P
  */

  // 拿到当前点击的元素
  tableClick.target = getTarget(e)
  const target = tableClick.target

  // 拿到点击元素上的自定义属性
  const field = target.dataset.field
  const index = target.dataset.index

  // 只有span和td有事件处理函数（其他都是undefined）
  if (field) {
    // 拿到当前元素的值
    const tdText = target.innerText
    // 创建input元素
    tableClick.oInput = createInput(tdText)     // 存到tableClick.oInput中原因是：外部的也要使用
    // 插入到td中
    target.appendChild(tableClick.oInput)
    // input内容全选
    tableClick.oInput.select()

    tableClick.field.value = field    // 因为上面已经转换成了ref值，所以要用.value来修改值
    tableClick.index.value = index

    bindInputEvent()
    // 修改数据中...
    tableClick.socket.emit('changeStatus', true)
  }

}
// window点击事件处理函数
function handleWindowClick() {
  // 首先要判断oInput是存在页面中的
  if (tableClick.oInput) {
    updataUserList(tableClick.oInput.value)
    // 移除input
    removeInput()
  }
}

function bindInputEvent() {
  tableClick.oInput.addEventListener('click', handleStopPropagation, false)
  tableClick.oInput.addEventListener('input', handleInput, false)
}

function unbindInputEvent() {
  tableClick.oInput.removeEventListener('click', handleStopPropagation, false)
}

function handleInput(e) {
  updataUserList(e.target.value)
}

function updataUserList(value) {
  tableClick.socket.emit('changeData', {
    field: tableClick.field.value,
    index: tableClick.index.value,
    value
  })
}

// 移除input
function removeInput() {
  tableClick.target.removeChild(tableClick.oInput)
  unbindInputEvent()
  tableClick.target = null
  tableClick.oInput = null
  // 修改数据中...
  tableClick.socket.emit('changeStatus', false)
}

// 阻止冒泡
function handleStopPropagation(e) {
  e.stopPropagation()  // 阻止冒泡  stopPropagation：停止传播
}

// 创建input标签元素
function createInput(value) {
  const oInput = document.createElement('input')

  oInput.type = 'text'
  oInput.value = value

  oInput.style.cssText = `
    width: 100%;
    height: 100%;
    border: none;
    box-sizing: border-box;
    position: absolute;
    top:0;
    left:0;
  `

  return oInput
}

// 点击td里的span元素也要有点击事件
function getTarget(e) {
  // 获取当前点击到的元素标签名，并转换为小写
  const tagName = e.target.tagName.toLowerCase()

  switch (tagName) {
    case 'span':
      return e.target.parentNode   // 返回td中的span的父元素，也就是td，因为span是td的子元素
    case 'td':
      return e.target
    default:
      return e.target
  }
}

export default tableClick